import time
from os import path

import yaml
from appium import webdriver

from config import settings
from common import check_port, release_port, adb_connect, check_devices, multi_appium_start
from common import logger
from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener


# 自定义的事件监听器类
class CustomEventListener(AbstractEventListener):
    """
    before_navigate_to(url, driver): 在导航到指定 URL 之前触发。
    after_navigate_to(url, driver): 在导航到指定 URL 之后触发。
    before_navigate_back(driver): 在执行浏览器的返回操作之前触发。
    after_navigate_back(driver): 在执行浏览器的返回操作之后触发。
    before_navigate_forward(driver): 在执行浏览器的前进操作之前触发。
    after_navigate_forward(driver): 在执行浏览器的前进操作之后触发。
    before_find(by, value, driver): 在查找元素之前触发。
    after_find(by, value, driver): 在查找元素之后触发。
    before_click(element, driver): 在点击元素之前触发。
    after_click(element, driver): 在点击元素之后触发。
    before_change_value_of(element, driver): 在改变元素值之前触发。
    after_change_value_of(element, driver): 在改变元素值之后触发。
    before_execute_script(script, driver): 在执行脚本之前触发。
    after_execute_script(script, driver): 在执行脚本之后触发。
    before_quit(driver): 在退出驱动程序之前触发。
    after_quit(driver): 在退出驱动程序之后触发。
    on_exception(exception, driver): 在遇到异常情况时触发。
    """

    def before_click(self, element, driver):
        logger.info(f"将要点击元素：{element}")
        logger.info(f"id：{element.get_attribute('resource-id')},text:{element.text}")
        # 在这里可以添加你需要执行的代码


def multi_appium_desired(config_file, device_dict):
    driver_list = []
    with open(path.join(settings.CONFIG_PATH, config_file), 'r', encoding='utf-8') as file:
        data = yaml.load(file, Loader=yaml.FullLoader)
    app_path = path.join(settings.APPS_PATH, data['appname'])
    desired_caps = {}
    desired_caps['platformName'] = data['platformName']
    desired_caps['platformVersion'] = data['platformVersion']
    desired_caps['deviceName'] = data['deviceName']
    desired_caps['app'] = app_path
    desired_caps['appPackage'] = data['appPackage']
    desired_caps['appActivity'] = data['appActivity']
    desired_caps['noReset'] = data['noReset']
    desired_caps['unicodeKeyboard'] = data['unicodeKeyboard']
    desired_caps['resetKeyboard'] = data['resetKeyboard']
    desired_caps['ANDROID_UIAUTOMATOR'] = data['ANDROID_UIAUTOMATOR']
    desired_caps['chromedriverUseSystemExecutable'] = data['chromedriverUseSystemExecutable']
    desired_caps['newCommandTimeout'] = data['newCommandTimeout']

    # 启动appium服务
    num = len(device_dict.keys())
    port_list = [4723 + 2 * i for i in range(num)]
    for p in port_list:
        if not check_port(data['ip'], p):
            logger.info("端口被占用")
            release_port(p)
            time.sleep(3)
    multi_appium_start(num)

    # 连接设备
    device_list = [x[1] for x in list(device_dict.values())]
    if not check_devices(device_list):
        for device in device_list:
            if not adb_connect(device):
                logger.error(f"连接设备{device}失败，请检查设备连接和配置文件后重试！")
                raise
    # 实例化driver
    for k, v in device_dict.items():
        desired_caps['udid'] = v[1]
        desired_caps['real'] = v[2]
        driver = webdriver.Remote('http://' + str(data['ip']) + ':' + str(k) + '/wd/hub', desired_caps)
        # 用 EventFiringWebDriver 包装原始的驱动
        wrapped_driver = EventFiringWebDriver(driver, CustomEventListener())
        # driver.implicitly_wait(5)
        driver_list.append(wrapped_driver)
    return driver_list


if __name__ == '__main__':
    #           appium端口：[设备名称,设备udid,是否实盘标识]
    device_dict = {"4723": ["夜神模拟器", "127.0.0.1:62001", False],
                   "4725": ["夜神模拟器(1)", "127.0.0.1:62025", True],
                   }
    multi_appium_desired('multi_desired_caps.yaml', device_dict)
